{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Bokeh Structure Graph Example\n",
    "\n",
    "The Bokeh Structure Graph allows one to browse a model and its submodels, and to investigate its attributes."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from bokeh.models.util import generate_structure_plot\n",
    "from bokeh.plotting import figure\n",
    "from bokeh.io import output_notebook, show\n",
    "output_notebook()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Create a figure\n",
    "\n",
    "First we create a figure to analyze."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "X = np.linspace(-1,1,100)\n",
    "Y = X + np.random.normal(size=X.shape)\n",
    "f=figure(width=400,height=400)\n",
    "_=f.line(x=X,y=Y,color='blue',line_width=3,alpha=.5)\n",
    "_=f.line(x=X,y=X,color='red',line_width=3)\n",
    "show(f)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Simple Public API"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "show(generate_structure_plot(f))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### The  _BokehStructureGraph class\n",
    "\n",
    "We create a BokehStructureGraph object from this figure."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from bokeh.models.util import structure as st"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "BSG=st._BokehStructureGraph(f)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Properties of the Structure Graph\n",
    "### Networkx graph of submodels\n",
    "\n",
    "There are three resources available from the BokehStructureGraph.  The first is a networkx graph\n",
    "that has one mode for each submodel, identified by the model id, together with the name of that submodel. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "for x in BSG.graph.nodes(data=True):\n",
    "    print(x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Dataframe of attributes with values, types, and docstrings\n",
    "\n",
    "Next, there is a pandas dataframe that contains one entry for each attribute of each model, together with the value of the attribute, its type (a bokeh property) and its docstring."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "BSG.property_df\n",
    "BSG.property_df['doc']=BSG.property_df['doc'].str.replace('\\n','')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "pd.set_option('max_colwidth',None)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "BSG.property_df"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Graphical representation\n",
    "\n",
    "Finally there is a bokeh model that displays the graphical structure of the model and its submodels.  Clicking on a node\n",
    "reveals the attributes of that model and their values."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "show(BSG.model)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "bokeh-dev",
   "language": "python",
   "name": "bokeh-dev"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
